package com.beta.auth.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.util.Base64;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author : liuxuan
 * @date Date : 2021年09月15日
 */
@Data
@Slf4j
@Service
public class HttpService {

    /**
     * Y / N
     */
    @Value("${net.proxy.enable}")
    private String enable;
    /**
     * http/socket
     */
    @Value("${net.proxy.type}")
    private String type;
    /**
     * ip
     */
    @Value("${net.proxy.host}")
    private String host;
    /**
     * port
     */
    @Value("${net.proxy.port}")
    private int port;
    /**
     * 用户名
     */
    @Value("${net.proxy.user}")
    private String user;
    /**
     * 密码
     */
    @Value("${net.proxy.passwd}")
    private String passwd;


    public String post(String url, Map<String, Object> param) {
        HttpResponse response = null;
        try {
            HttpRequest request = HttpRequest.post(url).timeout(20000);
            if (null != param && !param.isEmpty()) {
                request.form(param);
            }
            if (!"Y".equals(enable)) {
                response = request.execute();
                return response.body();
            }
            if (StringUtils.isNotBlank(user)) {
                request.basicProxyAuth(user, passwd);
            }
            if ("http".equals(type)) {
                request.setHttpProxy(host, port);
            } else {
                sockRequest(request);
            }
            response = request.execute();
            return response.body();
        } finally {
            if (!Objects.isNull(response)) {
                response.close();
            }
        }
    }

    private void sockRequest(HttpRequest request) {
        request.setProxy(new Proxy(Proxy.Type.SOCKS,
                new InetSocketAddress(host, port)));
        if (StringUtils.isNotBlank(user)) {
            java.net.Authenticator.setDefault(new java.net.Authenticator() {
                private PasswordAuthentication authentication = new PasswordAuthentication(user, passwd.toCharArray());

                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return authentication;
                }
            });
        }
    }

    public String post(String url, String param) {
        HttpResponse response = null;
        try {
            HttpRequest request = HttpRequest.post(url).timeout(20000);
            if (StringUtils.isNotBlank(param)) {
                request.body(param);
            }
            if (!"Y".equals(enable)) {
                response = request.execute();
                return response.body();
            }

            if ("http".equals(type)) {
                request.setHttpProxy(host, port);
                if (StringUtils.isNotBlank(user)) {
                    request.basicProxyAuth(user, passwd);
                }
            } else {
                sockRequest(request);
            }
            response = request.execute();
            return response.body();
        } finally {
            if (!Objects.isNull(response)) {
                response.close();
            }
        }
    }

    public String get(String url, Map<String, Object> param) {
        HttpRequest request = HttpRequest.get(url).timeout(20000);
        if (!CollectionUtils.isEmpty(param)) {
            request.form(param);
        }
        if (!"Y".equals(enable)) {
            try (HttpResponse response = request.execute()) {
                return response.body();
            }
        }
        if (StringUtils.isNotBlank(user)) {
            request.basicProxyAuth(user, passwd);
        }
        if ("http".equals(type)) {
            request.setHttpProxy(host, port);
        } else {
            sockRequest(request);
        }
        try (HttpResponse response = request.execute()) {
            return response.body();
        }
    }

    /**
     * 互联网图片转Base64
     * @param imgUrl
     * @return
     */
    public String imageUrlToBase64(String imgUrl) {
        try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {
            HttpRequest request = HttpRequest.get(imgUrl).timeout(20000);
            if ("Y".equals(enable)) {
                if (StringUtils.isNotBlank(user)) {
                    request.basicProxyAuth(user, passwd);
                }
                if ("http".equals(type)) {
                    request.setHttpProxy(host, port);
                } else {
                    sockRequest(request);
                }
            }
            try (HttpResponse res = request.execute(); InputStream is = res.bodyStream()) {
                //创建一个Buffer字符串
                byte[] buffer = new byte[1024];
                //每次读取的字符串长度，如果为-1，代表全部读取完毕
                int len = 0;
                //使用输入流从buffer里把数据读取出来
                while ((len = is.read(buffer)) != -1) {
                    //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
                    outStream.write(buffer, 0, len);
                }
                // 对字节数组Base64编码
                return encode(outStream.toByteArray());
            }

        } catch (IOException e) {
            log.error("图片转base64异常，图片地址：{}，异常信息：{}", imgUrl, e.getMessage(), e);
        }
        return null;
    }

    /**
     * 图片转字符串
     *
     * @param image 图片Buffer
     * @return Base64编码
     */
    private static String encode(byte[] image) {
        return replaceEnter(new String(Base64.getEncoder().encode(image)));
    }

    /**
     * 字符替换
     *
     * @param str 字符串
     * @return 替换后的字符串
     */
    private static String replaceEnter(String str) {
        String reg = "[\n-\r]";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(str);
        return m.replaceAll("");
    }

}
